Maxsavin, я каждой карте из кампаний даю свой кэш, чтобы не перепуталось ничего.
Не знаю, что получилось бы, сделай я один кэш-файл на всю кампу и грузи карты потом не по порядку. Проверять не буду. Кампания - это пак карт.
Второй комп сломан поэтому проверить не могу, почему у меня подозрение, что оно должно работать.... Хотя могу и ошибаться, нормально делал карты года 2 назад.
Если ты открыл доту мпкью-редактором и похимичил там - эторедактор делает архив карты примерно на 100 кб больше, так что возможно, что и правда слишком большой вес.
Я хз зачем ты лезешь в эти карты, но кириллица занимает 2 символа, а не 1 для справки. Больше добавить нечего.
ты ошибаешься
OrderId2String('Aeye') возвращает "" (пустая строка) т.к. приказ 'Aeye' не имеет строкового представления
"order=" + "" = "order="
всё работает
Bravotan, вот список функций (так же есть в теме с мх)
Функций очень много, некоторые работают своеобразно читайте тему с мх и задавайте там вопросы по функциям.
Нет. Я пока хочу достроить карту на GUI, думаю мне осталось дней 10-30 работать, а буду ли следующую делать - под вопросом. Не хочется тратить время на изучение jass из-за пустяка! Однако Я использовал Custom Script, но это было содрано с одного сайта, а вот чтобы делать самому нужно сначала полностью изучить язык. Либо знаю, либо нет, чуть-чуть не считается!
Что касается wait, то если не это то что тогда?
Опытным путём сам установил что в процесс ничего не вклинивается. Можно использовать Триггер как Функцию и ссылаться на него в другом Триггере. По сути, это и есть функция, если глянуть на jass. Вопрос закрыт.
Вот как должен выглядеть полностью правильный триггер без утечек, единственная утечка создастся только при первом использовании, это я так понял переменная группы, ее обнулять нельзя, иначе скил будет работать только раз.
для того что бы пикать юнитов с москитами нужно провернуть один несложный фокус
при создании такого типа даммиков заносишь их в группу
в нужный момент обращаешься в группе и отнимаешь у даммиков москиты
пикаешь как обычных юнитов
обращаешься к группе и возвращаешь им москитов
Нет, способности группировать можно только а уровне спеллбука.
Но.
можно присваивать способность в переменную с массивом, к примеру ability[n+1], где n - целое число для группы. И потом в нужный момент удалять циклом все способности. Минус в том, что на каждую группу нужно будет держать свое целое число
Только ручное применение. Этот параметр определяет как будет использоватся заклинание если отдать приказ сразу группе юнитов с этой способностью. Если эта галка стоит, то способность использует только один из группы, если нет - то сразу вся группа.
У остальных насколько я знаю, захардкожено в движке.
Поиграйся с орбэффектами, добавляя в разрешённые цели необходимую клиссификацию. А вообще, просто поступи так:
Атака есть изначально, но при ударе юнитом по камню или дереву, проверка, имеет ли он кирку, и если да, тогда ролить переменную от N до N, и если равно N - создать такой то ресурс.
Можно также сделать систему с уровнем кирки(ну типа деревянная каменная железная алмазная окда), и по уровню кирки определять коилчество последовательностей "Иначе": Роллить первое число от 1 до 100 - камень. Если не выпал, но кирка у тебя выше деревянной - Роллить от 1 до 200 - железо. Если не выпало, но кирка выше каменной - роллить от 1 до 1000 - аметист, и т.д.
что за костыли блин
событие - приводит способность в действие
условие - применённая способность == божественный щит
действия:
unit u=GetTriggerUnit()
SetUnitVertexColor(u,0,0,0,255)
TriggerSleepAction(15) // здесь указываем время действия способности
SetUnitVertexColor(u,255,255,255,255)
если время действия зависит от уровня то юзай арифметику как писали выше
в твоём случае это 2 + (уровень способности * 2)
Сделано на увечии некроманта, время действия 0.01 сек, эффект смертельного союза на кастере и цели (красивый луч это как раз и есть эффект от дарк пакта) ну и перемещение через SetUnitPosition цель на место кастера, а кастера на место цели через SetUnitX\Y в опен доте можно глянуть, простейший триггерный спелл.
Ну возьмите другую абилку, сфера связана с оружием чародея крови если что, там он при касте пуляет сверу в место каста, сферы летают вокруг чародея крови по сложным орбитам, это стандартное поведение абилки. Возьмите абилку предмету на бонус защиты или статов и укажите там эффект и точку крепления.
SetUnitPosition довольно тяжелая операци, юзайте SetUnitX\Y в конце полета юзай SetUnitPosition для того чтобы юнит не залетел в непроходимое место.
Фильтр просто ужас, ну кто так фильтры делает?
Проверка на 'Aloc', я в ужасе на кой черт проверять на дамми если GropEnumUnitsInRange\Rect не выделяет москитов, тока EnumOfPlayer может пикнуть москитов, остальное не пикает их, на то они и москиты...
Вот как выглядит нормальный фильтр без локалок и прочего
function EnemyFilter takes nothing returns boolean
set bj_lastFilterUnit = GetFilterUnit( )
return GetUnitState( bj_lastFilterUnit, UNIT_STATE_LIFE ) > 0.405 and IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and not( IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MAGIC_IMMUNE ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MECHANICAL ) or IsUnitInvulnerable( bj_lastFilterUnit ) )
endfunction
UnitDamageTargetEx - красиво но нафиг ненужно обводить в отдельную функцию с тучей аргументов + жутко неудобно, 100500 аргументов у функции и фиг знает за что какой от вечает, прямо так UnitDamageTarget, без отдельной функции.
Туча констант, тоже хорошо тока длят наработок, на деле ставь конкретные значения или юзай Difine vjass'a.
Это лежит в слк таблице, сам тип юнита это - РО код, 'hpea' - peasant, это целое число, но в 256 ричной системе исчисления.
Были просто функции которые из текста делают РО код, вводишь -spawn h000'и появляется юнит нужного тебе типа...
а) Создай 2 переменные-массива по типу "боевая единица" (массив - чтобы для каждого игрока, мы ведь за мультиплеер трем, прально?), назови типа MyChampion и MyChampionDummy.
б) подготовь невидимого героя-пустышку с нужной тебе иконкой, убери ману, если у чемпиона ее нет. Убери ему радиус обзора, убери галочки типа "отмечать на мини-карте" - остальные - опционально.
В дальнейшем мы будем синхронизировать пустышку и реального чемпиона, создавая видимость одной боевой единицы.
Итак, наш первый триггер:
в) Отследи первое появление чемпиона, когда это случится - создай для игрока героя-пустышку. Соответственно сделай MyChampion [number of (Owner of trained unit)]= last trained unit, следующей строчкой создай того самого героя-пустышку для (owner of trained unit) и сделай MyChampionDummy = last created unit. Теперь мы прочно связали этих чуваков. Этот же триггер запускает остальные.
г) Отслеживание здоровья. Сделай изначально выключенный цикличный триггер, там, каждые 0.3 секунды. Триггер запускается пунктом в). Каждые 0.3 секунды меняй здоровье героя (чья икона висит, надо чтобы она соответствовала, прально?) в % на здоровье самого чемпиона.
д) пропищи событие, мол, если выбирает игрок своего героя (кликая на иконку) выбирается чемпион
е) убивай героя вместе с чемпионом
ж) отключай триггеры с проверкой и выбором, пока чемпион мертв
з) не забывай обновлять переменную чемпиона с каждым новым чемпионом.
Пока нет желания разбираться, что у тебя так, а что не так. Но вижу, что переменная Window не назначена окну, а ещё как бы создаются в цикле одновременно 10 окон, которые потом все одновременно ждут 50 секунд. Вот скрин действий триггера вместо двух твоих, секунда ожидания поставлена для того, чтобы увидеть пропадание окна таймера.
Через что уничтожаешь? Если через килл, то конечно умирает и нейтральный.
Если наносить от какого-то даммика урон в мильены, то не умрет нейтральный.
Можно от даммика развеяние нежити за 0.01 сек.
Заменять можно, внося значение золота в переменную и потом, создавая новый рудник, ставить количество золота в него из переменной, благо это даже в ГУИ реализовано.
Можно сделать способность на основе "превращения в зомби" с передачей контроля игроку. И сделать дамми работников, которые будут в невидимости таскать золото, в зависимости от кол-во рабов на борту рудника.
Можно сделать невидимое "Древо Жизни" которое привязано к зданию и живет до тех пор, пока живет главное здание, главное связать здания триггерно.
Я придумал закинуть пустить корни в книгу заклинаний и заблокировал ее, в вобщем оплетение работает, сейчас другая проблема в другом вопросе))
у модели есть такой аттач (скребка) BitthLink вроде как так вот если вообще не нужна она, то удаляй, если нужна то настрой ее видимость, в ножных кадрах, чтобы она была видно только при анимации birth
Какие декорации? Пытаешься навести на дерево или что? Вот, если юниты выделены у игрока, и их наводишь на дерево или на бочок/стены, то можно отловить приказ. Но не все юниты наводятся на дерево (только рабочие или каменный голем у ночных эльфов), даже игрок без юнитов не может выбрать деревце.
Но обычно когда игрок просто щелкает и наводит на такие декорации как бочок или ворота, то никак это отследить нельзя Стандартным способом никак, такого события нет =(( Если надо делать невыделяемым, то можно переделать декор на дерево попробовать, но на ворота и бочок зачем такое делать?
function StringToPlayerColor takes string color returns playercolor
set color = StringCase(color, false)
if color == "red" then
return PLAYER_COLOR_RED
elseif color == "blue" then
return PLAYER_COLOR_BLUE
elseif color == "teal" then
return PLAYER_COLOR_CYAN
elseif color == "purple" then
return PLAYER_COLOR_PURPLE
elseif color == "yellow" then
return PLAYER_COLOR_YELLOW
elseif color == "orange" then
return PLAYER_COLOR_ORANGE
elseif color == "green" then
return PLAYER_COLOR_GREEN
elseif color == "pink" then
return PLAYER_COLOR_PINK
elseif color == "gray" then
return PLAYER_COLOR_LIGHT_GRAY
elseif color == "light blue" then
return PLAYER_COLOR_LIGHT_BLUE
elseif color == "dark green" then
return PLAYER_COLOR_AQUA
elseif color == "brown" then
return PLAYER_COLOR_BROWN
elseif color == "maroon" then
return PLAYER_COLOR_MAROON
elseif color == "navy" then
return PLAYER_COLOR_NAVY
elseif color == "turquoise" then
return PLAYER_COLOR_TURQUOISE
elseif color == "violet" then
return PLAYER_COLOR_VIOLET
elseif color == "wheat" then
return PLAYER_COLOR_WHEAT
elseif color == "peach" then
return PLAYER_COLOR_PEACH
elseif color == "mint" then
return PLAYER_COLOR_MINT
elseif color == "lavender" then
return PLAYER_COLOR_LAVENDER
elseif color == "coal" then
return PLAYER_COLOR_COAL
elseif color == "snow" then
return PLAYER_COLOR_SNOW
elseif color == "emerald" then
return PLAYER_COLOR_EMERALD
elseif color == "peanut" then
return PLAYER_COLOR_PEANUT
endif
return null
endfunction
function StringToPlayer takes string color returns player
local integer i
set bj_setPlayerTargetColor = StringToPlayerColor(color)
if bj_setPlayerTargetColor != null then
set i = 1
loop
set bj_forceRandomCurrentPick = Player(i)
if GetPlayerSlotState(bj_forceRandomCurrentPick) == PLAYER_SLOT_STATE_PLAYING and /*
*/ GetPlayerColor(bj_forceRandomCurrentPick) == bj_setPlayerTargetColor then
return bj_forceRandomCurrentPick
endif
set i = i + 1
exitwhen i == bj_MAX_PLAYERS
endloop
endif
return null
endfunction
function KickPlayer takes nothing returns boolean
call KillUnit(GetFilterUnit())
return false
endfunction
function MyTrig_Actions takes nothing returns nothing
local string color = GetEventPlayerChatString()
local player p = StringToPlayer(SubString(color, 3, StringLength(color)))
if p != null then
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, Filter(function KickPlayer))
set p = null
endif
endfunction
function InitMyTrig takes nothing returns nothing
set gg_trg_My = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_My, Player(0), "gg", false )
call TriggerAddAction( gg_trg_My, function MyTrig_Actions )
endfunction
Пусть переменная А считает игроков, а переменная B считает кнопки.
Перед циклом B ставим на 0, если игрок есть, увеличиваем В и записываем в массив[В] твою кнопку.
function GetRandomPlayerIndex takes nothing returns integer
set udg_Buf_A = 0
set bj_forLoopAIndex=0 //red
set bj_forLoopAIndexEnd=10 //light blue
loop
exitwhen(bj_forLoopAIndex>bj_forLoopAIndexEnd)
if(GetPlayerSlotState(Player(bj_forLoopAIndex))==PLAYER_SLOT_STATE_PLAYING)and(GetPlayerController(Player(bj_forLoopAIndex)))==MAP_CONTROL_USER)and(udg_AccEmpPlayer[bj_forLoopAIndex]==false)then
set udg_PlayersPlay[udg_Buf_A]=Player(bj_forLoopAIndex)
set udg_Buf_A=(udg_Buf_A+1)
endif
set bj_forLoopAIndex=bj_forLoopAIndex+1
endloop
set udg_Random=GetRandomInt(0,udg_Buf_A)
set udg_RndPlayer=udg_PlayersPlay[udg_Random]
return udg_RndPlayer
endfunction
Доступ только для одного - никак.
Но ты можешь внутри блога или проекта создать скрытый ресурс, там есть галочка такая. Такой ресурс могут видеть только участники проекта и в зависимости от настроек прав в проекте.
Сумрак действует только на скрытые комментарии.
ArchOracle, есть такая вещь как мемхак и есть такая функция как HideAbilityButton, она вам точно поможет (если сможете подкрутить мемхак), но сразу скажу, лично я её ещё не проверял.
Но в вашем случае скорее всего придётся, иметь спелбук с этой способностью, а старую надо будет удалить, и потом ещё не забыть выставить уровень способности, а про скрытие спел бука вам уже товарисч сверху ответил
берёшь содержимое бж функций с сайта
и копируешь себе в блокнотик
по поводу русификации копайся в файлах джнгп
мб найдёшь где то файлик с именами
либо сноси свой вар нафиг и ставь англ верию
Делаешь, наверное, неправильно. Сначала тебе нужно выделить те декорации (копировать, вырезать), потом жмешь вставить (у тебя появится возможность выбрать место, куда ты их хочешь поставить, будут видны сами объекты, которые двигаются за курсором мыши). После этого ничего не жмешь и идешь в пункт Правка и жмешь Повернуть.../Отразить..., как тебе нужно, и только после всего этого ставишь на карту повернутый вариант.
Короче порылся в ХГМ, потыкал, все испробывал, и сам нашел ответ, вот несколько моментов для того, чтобы заработал:
Требуется установленный Warcraft 3: The Frozen Throne последней версии 1.26a. Скачайте нормальный варкрафт 3, а то попадаются урезанные или нерабочие версии. Лучше оригинальную версии приобрести, и обновить. Хотя пиратки тоже неплохи. Вот использую сборкой от R.G. Mechanics
Путь к программе НЕ ДОЛЖЕН содержать русских символов
Совершайте установку в отдельную от Warcraft 3 папку
Рекомендуется приостановить антивирусные программы до установки, потом выполнить установку, затем добавить папку c JNGP в исключения, и потом только снова включить антивирусы. Эта программа вторгается в процесс worldedit.exe, поэтому может считаться вредоносной
Не трогайте файл worldedit121.exe, он должен быть и в папке игры и в папке JNGP
Сначала "Сохранить карту", только потом "Проверка карты", а ещё иногда бывает лучше сохранять пару раз
Выше, это стандартное описание для работы. Если не сработает, пробуем вот, что:
Выставляем оптимальные настройки к JNGP, указанные на скрине (см. ссылку) xgm.guru/forum/showthread.php?t=13118 Обычно, эти настройки должны быть изначально после установки JNGP (ну мало ли пригодятся)
Теперь суть моей проблемы (не знаю, что из этих ниже пунктов сработало, но сработало):
Я установил игру и JNGP на рабочий стол. Потому что на диске С, в папках типа Program Files.(x86) и др. блокирует браундмер. Обычно требует назойливо для работы права администратора, очень раздражает. Но сомневаюсь, что заработало из-за этого. Раньше не мешало нисколько.
Запустить JNGP в режим совместимости. Заходим в свойство exe-шника. Поставил семерку.
Если UMS изначально включен, то выключить его и включить (Enable UMS). Потом перезапустить WE. Скорее всего из-за него.
Из-за UMS также бывают ошибки: могут выскачить 2-3 окна : что отсутствует TriggerClearActions и layerAll. Когда пропускаешь эти окна, просто нажав на ок, затем появляется ошибка с памятью и уже потом закрывается редактор. Происходят такие ошибки, если пытаешься открыть обычным редактором карту, отредактированную в JNGP. Такая ошибка происходит, если некорректно настроен UMS (выкл. потом вкл.). Такая ошибка происходит, если открыть обычным редактором взломанную карту, которая наверняка сделана в UMS и использует необычный jass и прочие преимущества JNGP. Ошибки с UMS могут иногда происходить, поэтому скорее всего пункт 10 поможет
Если UMS перестает работать (некорректно работает), а 10 пункт не помогает. То есть плагин UMS по каким-то причинам не запускается, а JNGP стоит галочка напротив UMS (говорит, что включен). Короче узнать, что он запущен, можно при открытий редактора вместо стандартного окна выскакивает окно UMS. Если не выскакивает, надо попробовать завести снова работать. Плагин может по каким-то причинам сломаться (один раз баловался в настройках JNGP). Пробуйте потом удалить JNGP и потом заново переустановить. Или выкл. и вкл, UMS затем выйти из jngp, удалить и заново переустановить
JNPG не рассчитан на этот распространённый русификатор. Если хочешь русский JNPG, то на сайте есть проект пользователя Пушистый FNWE.
Там не только нормальный перевод, но и много дополнительных функций.
вопервых ты в 1 и ту же ячейку пытаешся записать 2 значения (location и integer)
во вторых ты создаёш область по кординатам а следующей строчкой находиш эти же кординаты с помощью функций
в 3 ты сохранял точку в хэш и сразу же удалял её
и в 4 ты не инициализировал хэш
function Trig_SlayerUlt_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00V'
endfunction
function Ultaction takes nothing returns nothing
local timer st = GetExpiredTimer()
local integer sid = GetHandleId(st)
local unit su = LoadUnitHandle (udg_Hash, sid, 0)
if IsUnitType(GetEnumUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy( GetEnumUnit(), GetOwningPlayer(su)) == true then
call UnitDamageTargetBJ( su, GetEnumUnit(), 210.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
set su = null
endfunction
function UltimateRun takes nothing returns nothing
local timer st = GetExpiredTimer()
local integer sid = GetHandleId(st)
local unit su = LoadUnitHandle (udg_Hash, sid, 0)
local integer suid = GetHandleId(su)
local location suloc = LoadLocationHandle(udg_Hash, sid, 1)
local effect sueff = LoadEffectHandle (udg_Hash, sid, 2)
local real x = GetLocationX( suloc )
local real y = GetLocationY( suloc )
local rect surect = Rect( x - 600.00*0.5, y - 600.00*0.5, x + 600.00*0.5, y + 600.00*0.5 )
local location random = Location (GetRandomReal(x-600*.5,x+600*.5), GetRandomReal (y-600*.5, y+600*.5))
local integer sc = LoadInteger (udg_Hash, sid, 10)
call SetUnitPositionLoc( su, random )
call SetUnitAnimation( su, "attack" )
call AddSpecialEffectLocBJ( random, "Abilities\\Spells\\Human\\Thunderclap \\ThunderClapCaster.mdl" )
call DestroyEffectBJ ( GetLastCreatedEffectBJ() )
call AddSpecialEffectLocBJ( random, "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl" )
call DestroyEffectBJ ( GetLastCreatedEffectBJ() )
call ForGroupBJ ( GetUnitsInRangeOfLocAll(250.00, suloc), function Ultaction )
set bj_wantDestroyGroup=true
call SaveInteger(udg_Hash,sid,10,sc + 1)
if sc >= 10 then
call SetUnitPositionLoc( su, suloc )
call DestroyEffectBJ( sueff )
call SetUnitPathing( su, true )
call SetUnitInvulnerable( su, false )
call PauseUnitBJ( false, su )
call SetUnitVertexColorBJ( su, 100, 100, 100, 0.00 )
call PauseTimer(st)
call DestroyTimer(st)
call FlushChildHashtable(udg_Hash, sid)
endif
set suloc = null
set random = null
set st = null
set su = null
set sueff = null
endfunction
function Trig_SlayerUlt_Actions takes nothing returns nothing
local timer st = CreateTimer()
local integer sid = GetHandleId(st)
local unit su = GetTriggerUnit()
local integer suid = GetHandleId(su)
local location suloc = GetUnitLoc(su)
local effect sueff
local real x=GetUnitX(su)
local real y=GetUnitY(su)
call AddSpecialEffectTargetUnitBJ ( "hand right", su, "Abilities\\Weapons \\PhoenixMissile\\Phoenix_Missile.mdl" )
set sueff = GetLastCreatedEffectBJ()
call SetUnitPathing( su, false )
call SetUnitInvulnerable( su, true )
call PauseUnitBJ( true, su )
call SetUnitVertexColorBJ( su, 100, 100, 100, 50.00 )
call SaveUnitHandle(udg_Hash, sid, 0, su)
call SaveAgentHandle(udg_Hash, sid, 1, suloc)
call SaveAgentHandle(udg_Hash, sid, 2, sueff)
call SaveAgentHandle(udg_Hash, suid, 0, st)
call SaveInteger (udg_Hash, sid, 10, 1)
call TimerStart( st, .3, true, function UltimateRun )
set suloc = null
set st = null
set su = null
set sueff = null
endfunction
===========================================================================
function InitTrig_SlayerUlt takes nothing returns nothing
set gg_trg_SlayerUlt = CreateTrigger ( )
set udg_Hash=InitHashtable()
call TriggerRegisterAnyUnitEventBJ ( gg_trg_SlayerUlt, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition ( gg_trg_SlayerUlt, Condition( function Trig_SlayerUlt_Conditions ) )
call TriggerAddAction ( gg_trg_SlayerUlt, function Trig_SlayerUlt_Actions )
endfunction
Событие никак и никогда не удаляется, поэтому будет висеть.
Лагать не должно, т.к. событие просто висит в памяти и вар может только вылететь с fatal'ом при нехватки памяти. Для этого этих событий должно быть десятки тысяч, наверное....
» WarCraft 3 / Союз Рас
» WarCraft 3 / Конверт
» WarCraft 3 / Проблема с предметами в редакторе
» WarCraft 3 / Карта не работает в локальной сети.
» WarCraft 3 / Как работает функция ?!
» WarCraft 3 / Группа Способностей
» WarCraft 3 / Анимации Способностей
» WarCraft 3 / Как сделать способность ?
» WarCraft 3 / Эффект на посохе
» WarCraft 3 / Вопрос о texttag
» WarCraft 3 / Описание предмета
» WarCraft 3 / Смена ID объекта
» WarCraft 3 / Помощь с диалогом
» WarCraft 3 / Оплетенный рудник
» WarCraft 3 / Баг ;(
» WarCraft 3 / Выбор игроком
» WarCraft 3 / Не работают источники света
» Администрация XGM / Сумрак
» WarCraft 3 / Иконка
» WarCraft 3 / Получение точки применения способности ?
» WarCraft 3 / JNGP WE Ошибка при попытке создать карту
» WarCraft 3 / Ошибка
» WarCraft 3 / Как убрать тень предмета?
» WarCraft 3 / Радиус выбора героя
» WarCraft 3 / Динамические триггеры